const cron = require('node-cron');
const backupService = require('./backupService');
const emailService = require('./emailService');
const logger = require('../utils/logger');

class SchedulerService {
    constructor() {
        this.backupTask = null;
        this.schedule = process.env.BACKUP_SCHEDULE || '0 2 * * *'; // 默认每天凌晨2点
        this.isRunning = false;
    }

    validateCronExpression(expression) {
        return cron.validate(expression);
    }

    async performScheduledBackup() {
        if (this.isRunning) {
            logger.warn('备份任务正在运行中，跳过此次调度');
            return;
        }

        this.isRunning = true;
        const startTime = Date.now();
        
        try {
            logger.info('开始执行定时备份任务');
            
            // 执行备份
            const backupResult = await backupService.performBackup();
            
            // 发送成功邮件
            try {
                const emailResult = await emailService.sendBackupSuccess(backupResult);
                logger.info(`邮件发送结果: 成功发送给 ${emailResult.recipients} 个收件人`);
            } catch (emailError) {
                logger.error(`发送成功邮件失败，但备份已完成: ${emailError.message}`);
            }
            
            const duration = ((Date.now() - startTime) / 1000).toFixed(2);
            logger.info(`定时备份任务完成，耗时: ${duration}秒`);
            
        } catch (error) {
            const duration = ((Date.now() - startTime) / 1000).toFixed(2);
            logger.error(`定时备份任务失败，耗时: ${duration}秒, 错误: ${error.message}`);
            
            // 发送失败邮件
            try {
                await emailService.sendBackupFailure(error);
                logger.info('备份失败通知邮件已发送');
            } catch (emailError) {
                logger.error(`发送失败邮件也失败了: ${emailError.message}`);
            }
        } finally {
            this.isRunning = false;
        }
    }

    startScheduler() {
        if (!this.validateCronExpression(this.schedule)) {
            throw new Error(`无效的 cron 表达式: ${this.schedule}`);
        }

        if (this.backupTask) {
            logger.warn('定时任务已在运行，先停止现有任务');
            this.stopScheduler();
        }

        logger.info(`启动定时备份任务，调度表达式: ${this.schedule}`);
        
        this.backupTask = cron.schedule(this.schedule, async () => {
            await this.performScheduledBackup();
        }, {
            scheduled: true,
            timezone: 'Asia/Shanghai'
        });

        // 输出下次执行时间
        this.logNextExecutionTime();
        
        return {
            success: true,
            schedule: this.schedule,
            timezone: 'Asia/Shanghai',
            nextExecution: this.getNextExecutionTime()
        };
    }

    stopScheduler() {
        if (this.backupTask) {
            this.backupTask.stop();
            this.backupTask.destroy();
            this.backupTask = null;
            logger.info('定时备份任务已停止');
            return { success: true, message: '定时任务已停止' };
        } else {
            logger.warn('没有运行中的定时任务');
            return { success: false, message: '没有运行中的定时任务' };
        }
    }

    getStatus() {
        return {
            isRunning: this.backupTask ? true : false,
            isBackupInProgress: this.isRunning,
            schedule: this.schedule,
            timezone: 'Asia/Shanghai',
            nextExecution: this.getNextExecutionTime(),
            lastCheck: new Date().toISOString()
        };
    }

    getNextExecutionTime() {
        if (!this.backupTask) {
            return null;
        }
        
        try {
            // 这里简化处理，实际项目中可能需要更复杂的计算
            const now = new Date();
            const tomorrow = new Date(now);
            tomorrow.setDate(tomorrow.getDate() + 1);
            tomorrow.setHours(2, 0, 0, 0); // 假设是每天2点执行
            
            return tomorrow.toISOString();
        } catch (error) {
            return null;
        }
    }

    logNextExecutionTime() {
        const nextTime = this.getNextExecutionTime();
        if (nextTime) {
            logger.info(`下次备份时间: ${new Date(nextTime).toLocaleString('zh-CN')}`);
        }
    }

    updateSchedule(newSchedule) {
        if (!this.validateCronExpression(newSchedule)) {
            throw new Error(`无效的 cron 表达式: ${newSchedule}`);
        }

        const wasRunning = this.backupTask ? true : false;
        
        if (wasRunning) {
            this.stopScheduler();
        }

        this.schedule = newSchedule;
        
        if (wasRunning) {
            return this.startScheduler();
        }

        return {
            success: true,
            message: '调度表达式已更新',
            schedule: newSchedule
        };
    }

    async executeBackupNow() {
        logger.info('手动触发备份任务');
        await this.performScheduledBackup();
        return {
            success: true,
            message: '手动备份任务已完成',
            timestamp: new Date().toISOString()
        };
    }

    // 解析 cron 表达式为可读格式
    parseCronExpression(expression) {
        const parts = expression.split(' ');
        if (parts.length !== 5) {
            return '无效的表达式';
        }

        const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
        
        let description = '';
        
        if (minute === '0' && hour !== '*') {
            description += `每天 ${hour}:00`;
        } else if (minute !== '*' && hour !== '*') {
            description += `每天 ${hour}:${minute.padStart(2, '0')}`;
        } else {
            description = '自定义时间';
        }

        return description;
    }

    getScheduleDescription() {
        return this.parseCronExpression(this.schedule);
    }
}

module.exports = new SchedulerService(); 